package services.impl;

import services.*;
import entities.*;
import java.util.List;
import java.util.LinkedList;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.function.Predicate;
import java.util.Arrays;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BooleanSupplier;
import org.apache.commons.lang3.SerializationUtils;
import java.util.Iterator;

public class CreateTeamServiceImpl implements CreateTeamService, Serializable {
	
	
	public static Map<String, List<String>> opINVRelatedEntity = new HashMap<String, List<String>>();
	
	
	ThirdPartyServices services;
			
	public CreateTeamServiceImpl() {
		services = new ThirdPartyServicesImpl();
	}

	
	//Shared variable from system services
	
	/* Shared variable from system services and get()/set() methods */
			
	/* all get and set functions for temp property*/
				
	
	
	/* Generate inject for sharing temp variables between use cases in system service */
	public void refresh() {
		LabManageSystem labmanagesystem_service = (LabManageSystem) ServiceManager.getAllInstancesOf("LabManageSystem").get(0);
	}
	
	/* Generate buiness logic according to functional requirement */
	@SuppressWarnings("unchecked")
	public boolean createTeam(String id, String userId, String name, String message) throws PreconditionException, PostconditionException, ThirdPartyServiceException {
		
		
		/* Code generated for contract definition */
		//Get user
		User user = null;
		//no nested iterator --  iterator: any previous:any
		for (User u : (List<User>)EntityManager.getAllInstancesOf("User"))
		{
			if (u.getId().equals(userId))
			{
				user = u;
				break;
			}
				
			
		}
		//Get team
		Team team = null;
		//no nested iterator --  iterator: any previous:any
		for (Team t : (List<Team>)EntityManager.getAllInstancesOf("Team"))
		{
			if (t.getId().equals(id))
			{
				team = t;
				break;
			}
				
			
		}
		/* previous state in post-condition*/
 
		/* check precondition */
		if (StandardOPs.oclIsundefined(user) == false && user.getIdentity() == IdentityType.TEACHER && StandardOPs.oclIsundefined(team) == true) 
		{ 
			/* Logic here */
			Team t = null;
			t = (Team) EntityManager.createObject("Team");
			t.setId(id);
			t.setBelongTeacher(userId);
			t.setName(name);
			t.setIntroduce(message);
			EntityManager.addObject("Team", t);
			
			
			refresh();
			// post-condition checking
			if (!(true && 
			t.getId() == id
			 && 
			t.getBelongTeacher() == userId
			 && 
			t.getName() == name
			 && 
			t.getIntroduce() == message
			 && 
			StandardOPs.includes(((List<Team>)EntityManager.getAllInstancesOf("Team")), t)
			 && 
			true)) {
				throw new PostconditionException();
			}
			
		
			//return primitive type
			refresh();				
			return true;
		}
		else
		{
			throw new PreconditionException();
		}
		//string parameters: [id, userId, name, message] 
		//all relevant vars : t
		//all relevant entities : Team
	}  
	
	static {opINVRelatedEntity.put("createTeam", Arrays.asList("Team"));}
	 
	@SuppressWarnings("unchecked")
	public boolean createGroup(String id, String teamId, String name, String message) throws PreconditionException, PostconditionException, ThirdPartyServiceException {
		
		
		/* Code generated for contract definition */
		//Get team
		Team team = null;
		//no nested iterator --  iterator: any previous:any
		for (Team t : (List<Team>)EntityManager.getAllInstancesOf("Team"))
		{
			if (t.getId().equals(teamId))
			{
				team = t;
				break;
			}
				
			
		}
		//Get group
		Group group = null;
		//no nested iterator --  iterator: any previous:any
		for (Group g : (List<Group>)EntityManager.getAllInstancesOf("Group"))
		{
			if (g.getId().equals(id))
			{
				group = g;
				break;
			}
				
			
		}
		/* previous state in post-condition*/
 
		/* check precondition */
		if (StandardOPs.oclIsundefined(team) == false && StandardOPs.oclIsundefined(group) == true) 
		{ 
			/* Logic here */
			Group g = null;
			g = (Group) EntityManager.createObject("Group");
			g.setId(id);
			g.setBelongTeam(teamId);
			g.setName(name);
			g.setIntroduce(message);
			EntityManager.addObject("Group", g);
			
			
			refresh();
			// post-condition checking
			if (!(true && 
			g.getId() == id
			 && 
			g.getBelongTeam() == teamId
			 && 
			g.getName() == name
			 && 
			g.getIntroduce() == message
			 && 
			StandardOPs.includes(((List<Group>)EntityManager.getAllInstancesOf("Group")), g)
			 && 
			true)) {
				throw new PostconditionException();
			}
			
		
			//return primitive type
			refresh();				
			return true;
		}
		else
		{
			throw new PreconditionException();
		}
		//string parameters: [id, teamId, name, message] 
		//all relevant vars : g
		//all relevant entities : Group
	}  
	
	static {opINVRelatedEntity.put("createGroup", Arrays.asList("Group"));}
	 
	@SuppressWarnings("unchecked")
	public boolean handleTeamApply(String teamId, boolean agree) throws PreconditionException, PostconditionException, ThirdPartyServiceException {
		
		
		/* Code generated for contract definition */
		//Get apply
		Apply apply = null;
		//no nested iterator --  iterator: any previous:any
		for (Apply a : (List<Apply>)EntityManager.getAllInstancesOf("Apply"))
		{
			if (a.getAimId().equals(teamId) && a.getApplyType() == ApplyType.JOINTEAM)
			{
				apply = a;
				break;
			}
				
			
		}
		/* previous state in post-condition*/
 
		/* check precondition */
		if (StandardOPs.oclIsundefined(apply) == false) 
		{ 
			/* Logic here */
			StudentInTeam sit = null;
			sit = (StudentInTeam) EntityManager.createObject("StudentInTeam");
			if (agree == true)
			{
				sit.setTeamId(teamId);
				sit.setStudentId(apply.getBelongStudent());
				EntityManager.addObject("StudentInTeam", sit);
				EntityManager.deleteObject("Apply", apply);
				
				refresh();
				// post-condition checking
				if (!(true && 
				(agree == true ? sit.getTeamId() == teamId
				 && 
				sit.getStudentId() == apply.getBelongStudent()
				 && 
				StandardOPs.includes(((List<StudentInTeam>)EntityManager.getAllInstancesOf("StudentInTeam")), sit)
				 && 
				StandardOPs.excludes(((List<Apply>)EntityManager.getAllInstancesOf("Apply")), apply)
				 && 
				true : StandardOPs.excludes(((List<Apply>)EntityManager.getAllInstancesOf("Apply")), apply)
				 && 
				true))) {
					throw new PostconditionException();
				}
				
				//return code
				refresh();
				return true;
			}
			else
			{
			 	EntityManager.deleteObject("Apply", apply);
			 	
			 	refresh();
			 	// post-condition checking
			 	if (!(true && 
			 	(agree == true ? sit.getTeamId() == teamId
			 	 && 
			 	sit.getStudentId() == apply.getBelongStudent()
			 	 && 
			 	StandardOPs.includes(((List<StudentInTeam>)EntityManager.getAllInstancesOf("StudentInTeam")), sit)
			 	 && 
			 	StandardOPs.excludes(((List<Apply>)EntityManager.getAllInstancesOf("Apply")), apply)
			 	 && 
			 	true : StandardOPs.excludes(((List<Apply>)EntityManager.getAllInstancesOf("Apply")), apply)
			 	 && 
			 	true))) {
			 		throw new PostconditionException();
			 	}
			 	
			 	//return code
			 	refresh();
			 	return true;
			}
			
			
			
		
		}
		else
		{
			throw new PreconditionException();
		}
		//string parameters: [teamId] 
		//all relevant vars : apply sit
		//all relevant entities : Apply StudentInTeam
	}  
	
	static {opINVRelatedEntity.put("handleTeamApply", Arrays.asList("Apply","StudentInTeam"));}
	 
	@SuppressWarnings("unchecked")
	public boolean handleGroupApply(String groupId, boolean agree) throws PreconditionException, PostconditionException, ThirdPartyServiceException {
		
		
		/* Code generated for contract definition */
		//Get apply
		Apply apply = null;
		//no nested iterator --  iterator: any previous:any
		for (Apply a : (List<Apply>)EntityManager.getAllInstancesOf("Apply"))
		{
			if (a.getAimId().equals(groupId) && a.getApplyType() == ApplyType.JOINGROUP)
			{
				apply = a;
				break;
			}
				
			
		}
		/* previous state in post-condition*/
 
		/* check precondition */
		if (StandardOPs.oclIsundefined(apply) == false) 
		{ 
			/* Logic here */
			StudentInGroup sig = null;
			sig = (StudentInGroup) EntityManager.createObject("StudentInGroup");
			if (agree == true)
			{
				sig.setGroupId(groupId);
				sig.setStudentId(apply.getBelongStudent());
				EntityManager.addObject("StudentInGroup", sig);
				EntityManager.deleteObject("Apply", apply);
				
				refresh();
				// post-condition checking
				if (!(true && 
				(agree == true ? sig.getGroupId() == groupId
				 && 
				sig.getStudentId() == apply.getBelongStudent()
				 && 
				StandardOPs.includes(((List<StudentInGroup>)EntityManager.getAllInstancesOf("StudentInGroup")), sig)
				 && 
				StandardOPs.excludes(((List<Apply>)EntityManager.getAllInstancesOf("Apply")), apply)
				 && 
				true : StandardOPs.excludes(((List<Apply>)EntityManager.getAllInstancesOf("Apply")), apply)
				 && 
				true))) {
					throw new PostconditionException();
				}
				
				//return code
				refresh();
				return true;
			}
			else
			{
			 	EntityManager.deleteObject("Apply", apply);
			 	
			 	refresh();
			 	// post-condition checking
			 	if (!(true && 
			 	(agree == true ? sig.getGroupId() == groupId
			 	 && 
			 	sig.getStudentId() == apply.getBelongStudent()
			 	 && 
			 	StandardOPs.includes(((List<StudentInGroup>)EntityManager.getAllInstancesOf("StudentInGroup")), sig)
			 	 && 
			 	StandardOPs.excludes(((List<Apply>)EntityManager.getAllInstancesOf("Apply")), apply)
			 	 && 
			 	true : StandardOPs.excludes(((List<Apply>)EntityManager.getAllInstancesOf("Apply")), apply)
			 	 && 
			 	true))) {
			 		throw new PostconditionException();
			 	}
			 	
			 	//return code
			 	refresh();
			 	return true;
			}
			
			
			
		
		}
		else
		{
			throw new PreconditionException();
		}
		//string parameters: [groupId] 
		//all relevant vars : sig apply
		//all relevant entities : StudentInGroup Apply
	}  
	
	static {opINVRelatedEntity.put("handleGroupApply", Arrays.asList("StudentInGroup","Apply"));}
	 
	@SuppressWarnings("unchecked")
	public boolean dismissGroup(String groupId) throws PreconditionException, PostconditionException, ThirdPartyServiceException {
		
		
		/* Code generated for contract definition */
		//Get group
		Group group = null;
		//no nested iterator --  iterator: any previous:any
		for (Group g : (List<Group>)EntityManager.getAllInstancesOf("Group"))
		{
			if (g.getId().equals(groupId))
			{
				group = g;
				break;
			}
				
			
		}
		//Get sig
		StudentInGroup sig = null;
		//no nested iterator --  iterator: any previous:any
		for (StudentInGroup s : (List<StudentInGroup>)EntityManager.getAllInstancesOf("StudentInGroup"))
		{
			if (s.getGroupId().equals(groupId))
			{
				sig = s;
				break;
			}
				
			
		}
		/* previous state in post-condition*/
 
		/* check precondition */
		if (StandardOPs.oclIsundefined(group) == false && StandardOPs.oclIsundefined(sig) == true) 
		{ 
			/* Logic here */
			EntityManager.deleteObject("Group", group);
			
			
			refresh();
			// post-condition checking
			if (!(StandardOPs.excludes(((List<Group>)EntityManager.getAllInstancesOf("Group")), group)
			 && 
			true)) {
				throw new PostconditionException();
			}
			
		
			//return primitive type
			refresh();				
			return true;
		}
		else
		{
			throw new PreconditionException();
		}
		//string parameters: [groupId] 
		//all relevant vars : group
		//all relevant entities : Group
	}  
	
	static {opINVRelatedEntity.put("dismissGroup", Arrays.asList("Group"));}
	 
	@SuppressWarnings("unchecked")
	public boolean dismissTeam(String teamId) throws PreconditionException, PostconditionException, ThirdPartyServiceException {
		
		
		/* Code generated for contract definition */
		//Get team
		Team team = null;
		//no nested iterator --  iterator: any previous:any
		for (Team t : (List<Team>)EntityManager.getAllInstancesOf("Team"))
		{
			if (t.getId().equals(teamId))
			{
				team = t;
				break;
			}
				
			
		}
		//Get sit
		StudentInTeam sit = null;
		//no nested iterator --  iterator: any previous:any
		for (StudentInTeam s : (List<StudentInTeam>)EntityManager.getAllInstancesOf("StudentInTeam"))
		{
			if (s.getTeamId().equals(teamId))
			{
				sit = s;
				break;
			}
				
			
		}
		//Get group
		Group group = null;
		//no nested iterator --  iterator: any previous:any
		for (Group g : (List<Group>)EntityManager.getAllInstancesOf("Group"))
		{
			if (g.getBelongTeam().equals(teamId))
			{
				group = g;
				break;
			}
				
			
		}
		/* previous state in post-condition*/
 
		/* check precondition */
		if (StandardOPs.oclIsundefined(team) == false && StandardOPs.oclIsundefined(sit) == true && StandardOPs.oclIsundefined(group) == true) 
		{ 
			/* Logic here */
			EntityManager.deleteObject("Team", team);
			
			
			refresh();
			// post-condition checking
			if (!(StandardOPs.excludes(((List<Team>)EntityManager.getAllInstancesOf("Team")), team)
			 && 
			true)) {
				throw new PostconditionException();
			}
			
		
			//return primitive type
			refresh();				
			return true;
		}
		else
		{
			throw new PreconditionException();
		}
		//string parameters: [teamId] 
		//all relevant vars : team
		//all relevant entities : Team
	}  
	
	static {opINVRelatedEntity.put("dismissTeam", Arrays.asList("Team"));}
	 
	
	
	
	/* temp property for controller */
			
	/* all get and set functions for temp property*/
	
	/* invarints checking*/
	public final static ArrayList<String> allInvariantCheckingFunction = new ArrayList<String>(Arrays.asList());
			
}
